package chapter11;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Created with IntelliJ IDEA.
 * Description:
 *
 * @author lzy
 * @create 2018-04-16 下午2:19
 */
public class ProxyClassUtil implements MethodInterceptor {
    /*被代理对象*/
    private Object target;
    /*拦截器*/
    private Interceptor interceptor;

    /**
     * 生成CGLib代理对象
     *
     * @param object：目标对象
     * @param interceptor：拦截器
     * @return 代理对象
     */
    public static Object getBean(Object object, Interceptor interceptor) {
        // 使用当前类作为代理类
        ProxyClassUtil _this = new ProxyClassUtil();
        _this.target = object;
        _this.interceptor = interceptor;
        // CGLib enhancer增强类对象
        Enhancer enhancer = new Enhancer();
        // 设置增强类
        enhancer.setSuperclass(object.getClass());
        // 定义逻辑代理对象作为当前对象，
        // 要求当前代理对象实现MethodInterceptor方法
        enhancer.setCallback(_this);
        // 生成并返回代理对象
        return enhancer.create();
    }

    /**
     * 代理逻辑方法
     *
     * @param proxy：代理对象
     * @param method：方法
     * @param objects：方法参数
     * @param methodProxy：方法代理
     * @return 代理逻辑返回
     * @throws Throwable
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        if (interceptor == null) {
            return methodProxy.invokeSuper(proxy, objects);
        }
        Object result = null;
        // 是否产生异常
        boolean exceptionFlag = false;
        // before 方法
        interceptor.before(target);
        try {
            //反射原有方法
            result = methodProxy.invokeSuper(proxy, objects);
        } catch (Exception ex) {
            //如果出现异常则将flag置为true
            exceptionFlag = true;
        } finally {
            // after方法
            interceptor.after(target);
        }
        if (exceptionFlag) {
            //执行afterThrowing方法
            interceptor.afterThrowing(target);
        } else {
            //执行afterReturning方法
            interceptor.afterReturning(target);
        }
        return result;
    }
}
